#include <boost/shared_ptr.hpp>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/PosixThreadFactory.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TNonblockingServer.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/THttpServer.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TBufferTransports.h>

#include "server/ChatServiceServerHandler.h"
#include "server/ProcessorFactory.h"
#include "server/TNonblockingPushServer.h"

namespace at = apache::thrift;
namespace atp = apache::thrift::protocol;
namespace att = apache::thrift::transport;
namespace ats = apache::thrift::server;
namespace atc = apache::thrift::concurrency;

int main(int argc, char **argv) {
  boost::shared_ptr<server::ProcessorFactory> processorFactory(new server::ProcessorFactory());
  int port = 9090;
  boost::shared_ptr<atp::TProtocolFactory> protocolFactory(new atp::TBinaryProtocolFactory());
  boost::shared_ptr<att::TTransportFactory> inputTransFactory(new att::THttpServerTransportFactory());
    
  boost::shared_ptr<att::TTransportFactory> outputTransFactory(new att::THttpServerTransportFactory());

  // using thread pool with maximum 15 threads to handle incoming requests
  boost::shared_ptr<atc::ThreadManager> threadManager = atc::ThreadManager::newSimpleThreadManager(1);
  boost::shared_ptr<atc::PosixThreadFactory> threadFactory = boost::shared_ptr<atc::PosixThreadFactory>(new atc::PosixThreadFactory());
  threadManager->threadFactory(threadFactory);
  threadManager->start();

  ats::TNonblockingPushServer server(processorFactory,
  
                                     //ats::TNonblockingServer server(processorFactory,
                                     inputTransFactory,
                                     outputTransFactory,
                                     protocolFactory,
                                     protocolFactory,
                                     port,
                                     threadManager);

  server.serve();
  return 0;
}
